<script lang="ts" setup>
import { reactive, ref, watch } from 'vue'
import formCreate from '@form-create/element-ui'
import TinymceEditor from '@/components/sofastui/TinymceEditor/TinymceEditor.vue'
import JsonEditorVue from 'json-editor-vue'
import { formDialogTitles } from './constant'
import { http } from '@/services/request'
import type { FormRule, Api } from '@form-create/element-ui'
import type { IFormDialogTypeProps, IFormDialogProps } from './interface'
import type { IConfigProps } from '@/components/sofastui/AdvancedTable/interface'

// Types
interface ComponentProps {
  rule: FormRule
  config: IConfigProps
}

interface FormService {
  add: (data: Record<string, unknown>) => Promise<unknown>
  update: (data: Record<string, unknown>) => Promise<unknown>
}

// Register custom component
formCreate.component('TinymceEditor', TinymceEditor)
formCreate.component('JsonEditorVue ', JsonEditorVue)

// Props with defaults
const props = withDefaults(defineProps<ComponentProps>(), {
  rule: () => [],
  config: () => ({
    name: 'table',
    rowKey: 'id',
    url: '/',
    selection: false,
  }),
})

const emit = defineEmits(['success'])

// Reactive state
const saveLoading = ref(false)
const formDialog = reactive<IFormDialogProps>({
  top: '15vh',
  width: '860px',
  type: 'add',
  title: '新增',
  span: 12,
  visible: false,
})

const formData = ref<Record<string, unknown>>({})
const formApi = ref<Api | null>(null)
const formRules = ref<FormRule>(formCreate.parseJson(JSON.stringify(props.rule)))

const formOption = ref(
  formCreate.parseJson(
    JSON.stringify({
      row: { gutter: 20 },
      form: {
        inline: false,
        labelPosition: 'top',
        size: 'default',
        labelWidth: '225px',
        labelSuffix: ':',
      },
      globalEvent: {},
      globalData: {},
      resetBtn: {
        show: false,
        innerText: '重置',
      },
      submitBtn: {
        show: false,
        innerText: '提交',
      },
    }),
  ),
)

watch(
  () => props.rule,
  (newVal) => {
    formRules.value = formCreate.parseJson(JSON.stringify(newVal))
  },
)

// Services
const serve: FormService = {
  add: (data: Record<string, unknown>) =>
    http.request({
      url: props.config.url,
      method: 'POST',
      data,
    }),

  update: (data: Record<string, unknown>) =>
    http.request({
      url: props.config.url,
      method: 'PUT',
      data,
    }),
}

// Methods
const show = (type: IFormDialogTypeProps, data: Record<string, unknown> = {}): void => {
  formData.value = { ...data }
  formDialog.type = type
  formDialog.title = formDialogTitles[type]
  formDialog.visible = true
}

const submitHandle = async (): Promise<void> => {
  if (!formApi.value) return

  saveLoading.value = true
  try {
    await formApi.value.submit(async (formData: Record<string, unknown>) => {
      const id = formData[props.config.rowKey || 'id']
      const isUpdate = !!id

      await (isUpdate ? serve.update(formData) : serve.add(formData))

      ElMessage.success(isUpdate ? '更新成功' : '新增成功')
      formDialog.visible = false
      emit('success')
    })
  } catch (error) {
    console.error('Form submission error:', error)
  } finally {
    saveLoading.value = false
  }
}

const cancelHandle = (): void => {
  formApi.value?.resetFields()
  saveLoading.value = false
  formDialog.visible = false
}

const beforeCloseHandle = (done: () => void): void => {
  cancelHandle()
  done()
}

defineExpose({ show })
</script>

<template>
  <el-dialog
    :title="formDialog.title"
    v-model="formDialog.visible"
    :top="formDialog.top"
    :width="formDialog.width"
    :close-on-click-modal="false"
    :before-close="beforeCloseHandle"
    :append-to-body="true"
  >
    <form-create
      v-model:modelValue="formData"
      v-model:api="formApi"
      :rule="formRules"
      :option="formOption"
    />

    <template #footer>
      <span class="dialog-footer">
        <el-button type="primary" @click="submitHandle()" icon="CircleCheck" :loading="saveLoading">
          保 存
        </el-button>
        <el-button @click="cancelHandle()" icon="CircleClose"> 取 消 </el-button>
      </span>
    </template>
  </el-dialog>
</template>
